package LockTest;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class CyclicBarrierTest {

    private final static Logger logger = LoggerFactory.getLogger(CyclicBarrierTest.class);

    @Test
    public void test() throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(2);
        new Thread(() -> {
            logger.info("threadA start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                logger.info("threadA wait another thread ");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            logger.info("threadA end");
        }).start();
        new Thread(() -> {
            logger.info("threadB start");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                logger.info("threadB wait another thread ");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            logger.info("threadB end");
        }).start();
        TimeUnit.SECONDS.sleep(5);
    }

    /**
     * @desc: 高级用法
     * @method: testAdvance
     * @param: []
     * @return: void
     * @auther: zhipingzhang
     * @date: 2019/6/12 14:04
     */
    @Test
    public void testAdvance() throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(2, () -> {
            logger.info("额外任务执行，当前线程：" + Thread.currentThread().getName());
        });
        new Thread(() -> {
            logger.info("threadA start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                logger.info("threadA wait another thread ");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            logger.info("threadA end");
        }).start();
        new Thread(() -> {
            logger.info("threadB start");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                logger.info("threadB wait another thread ");
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            logger.info("threadB end");
        }).start();
        TimeUnit.SECONDS.sleep(5);
    }
}
